/**
 * Copyright © 2018 TaoYu (tracy5546@gmail.com)
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.baomidou.kaptcha;

import com.baomidou.kaptcha.exception.KaptchaIncorrectException;
import com.baomidou.kaptcha.exception.KaptchaRenderException;
import com.baomidou.kaptcha.exception.KaptchaTimeoutException;
import com.google.code.kaptcha.impl.DefaultKaptcha;
import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.util.ObjectUtils;

import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

import static com.google.code.kaptcha.Constants.KAPTCHA_SESSION_KEY;

/**
 * 谷歌默认验证码组件
 *
 * @author TaoYu
 */
@Slf4j
public class GoogleKaptcha implements Kaptcha {

    private Cache cache;

    private DefaultKaptcha kaptcha;

    @Autowired
    private HttpServletResponse response;

    public GoogleKaptcha(DefaultKaptcha kaptcha, Cache cache) {
        this.kaptcha = kaptcha;
        this.cache = cache;
    }

    @Override
    public String render() {
        return render(KAPTCHA_SESSION_KEY);
    }

    @Override
    public String render(String key) {
        response.setDateHeader(HttpHeaders.EXPIRES, 0L);
        response.setHeader(HttpHeaders.CACHE_CONTROL, "no-store, no-cache, must-revalidate");
        response.addHeader(HttpHeaders.CACHE_CONTROL, "post-check=0, pre-check=0");
        response.setHeader(HttpHeaders.PRAGMA, "no-cache");
        response.setContentType("image/jpeg");
        String sessionCode = kaptcha.createText();
        try (ServletOutputStream out = response.getOutputStream()) {
            cache.set(key, sessionCode, 900);
            ImageIO.write(kaptcha.createImage(sessionCode), "jpg", out);
            return sessionCode;
        } catch (IOException e) {
            throw new KaptchaRenderException(e);
        }
    }

    @Override
    public boolean validate(String code) {
        return validate(KAPTCHA_SESSION_KEY, code, 900);
    }

    @Override
    public boolean validate(String key, String code) {
        return validate(key, code, 900);
    }

    @Override
    public boolean validate(@NonNull String code, long second) {
        return validate(KAPTCHA_SESSION_KEY, code, 900);
    }

    @Override
    public boolean validate(String key, String code, long second) {
        String cacheCode = cache.get(key);
        if (!ObjectUtils.isEmpty(cacheCode)) {
            if (cacheCode.equalsIgnoreCase(code)) {
                cache.delete(key);
                return true;
            } else {
                throw new KaptchaIncorrectException();
            }
        } else {
            throw new KaptchaTimeoutException();
        }
    }


}

